package com.yuzf.netty.example.nio.chat.client;


import lombok.extern.slf4j.Slf4j;
import com.yuzf.netty.example.nio.chat.client.UserInputHandler;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Set;

/**
 * @ClassName ChatClient
 * @Description: 客户端
 * @Author yuzf
 * @Date 2020/6/23
 * @Version V1.0
 **/
@Slf4j
public class ChatClient {
    private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
    private static final int DEFAULT_SERVER_PORT = 12801;
    private static final String QUIT = "quit";
    private static final Integer DEFAULT_BUFFER_SIZE = 1024;

    private String host;
    private Integer port;
    private SocketChannel client;
    private ByteBuffer rbuffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
    private ByteBuffer wbuffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
    private Selector selector;
    private Charset charset = Charset.forName("UTF-8");

    public ChatClient() {
        this(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT);
    }

    public ChatClient(String host, Integer port) {
        this.host = host;
        this.port = port;
    }


    public void start() {
        try (
                SocketChannel sc = SocketChannel.open();
                Selector selec = Selector.open()
        ) {
            client = sc;
            client.configureBlocking(false);
            client.connect(new InetSocketAddress(host, port));
            selector = selec;
            client.register(selector, SelectionKey.OP_CONNECT);
            while (true){
                selector.select();
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                for (SelectionKey key:selectionKeys){
                    handle(key);
                }
                selectionKeys.clear();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void handle(SelectionKey key) throws IOException {
        //connect
        if(key.isConnectable()){
            SocketChannel client = (SocketChannel) key.channel();
            if(client.isConnectionPending()){
                client.finishConnect();
                new Thread(new UserInputHandler(this)).start();
            }
            log.info("已连接到服务器!!!");
            client.register(selector, SelectionKey.OP_READ);
        }else if(key.isReadable()){
            SocketChannel client = (SocketChannel) key.channel();
            String msg = receive(client);
            if (msg.isEmpty()){
                selector.close();
            }else {
                log.info(msg);
            }

        }
        //read

    }

    private String receive(SocketChannel client) throws IOException {
        rbuffer.clear();
        while (client.read(rbuffer)>0);
        rbuffer.flip();
        return String.valueOf(charset.decode(rbuffer));
    }

    public void send(String msg) throws IOException {
        if(msg.isEmpty()){
            return;
        }
        wbuffer.clear();
        wbuffer.put(charset.encode(msg));
        wbuffer.flip();
        while (wbuffer.hasRemaining()){
            client.write(wbuffer);
        }
    }
    public boolean readyToQuit(String msg) {
        return QUIT.equals(msg);
    }
    public static void main(String[] args) {
        new ChatClient().start();
    }


}
